package com.talkyun.utils.crypt;

import com.talkyun.utils.AesCipher;
import com.talkyun.utils.codec.Base62;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

import static com.talkyun.utils.crypt.KeyStringUtils.cleanKeyString;

public class KeyStringCrypt {
    public static String DEFAULT_PUBLIC_KEY = "1BIM4X56FO3ZSSQ3BW2GHAKJQYQDA7UY7G6WX3QOCMUBGPKFOLLKB4YAG6HOBO27LYHI7XC5TDCDF5PMRGJUDVANXISRLHZPJNERV6JKJKYZK7Q3HVYN4WB5OX3SKS52GVS6WMNQE642QUGPFFVDK7UNYQMYVV5TZ6YBRJJ7DTYKKXWBMGGBIH7IBABSNUI5Y2JL5GI2VG4U27TGU5FDKHS37XN54BAUJ3LF35R5HVHXBSOGMO62BMAGRLA426UO6WE5KSCLRHJGNNKAAKKINUH36IMMTW6NCBTCRWWYAOR4RVKHZIZUKRKWYRETL3S2CDKKCQ6D3XBYGFZL4OHED5ZCRMSUCCNBL66KA6WJHHS2VMQBW5QRNGKSOPQGOND5EM6TNVTXEYQPWFFQUGG263GKLLC7NFFMV4P65H4BSURWEOQIWJM52XPW6THAT2QG2XJFIR5FCIVSIFGYK53EA76EDY6X7BMORCXZJ2JN5NTHFZEJZCXHZJUJEINCXNMG2JNBVOTDS6MTLDI4HWSZKCBVOVQLJTBPGJPTBCCG2KZINY4MJTQRJWEKKIOX6NT6VGLO3NFWWU35RQ2UXBVY2YBKRJKYQBA2ARS37HL4CMPRGBLY2UXEHGBSEIHBX75UTWB7BWGAIVBEWI34E5SYSLHF4T6XDSB3S2KEWRANSSXKZBYTOJ4H6GASEC5DC24N6EJQR5HLME2MJAZL4HYVZBJPY7OXPNSLNURYXNYASAQ3XHM3SXQO5C3K2KM2J5EMH6EB55LTDBFGBC44OUWDOTOX6UMKS27UPEZV3CNMT7B72UYIQ26SV5ZL6BBNUWCA2HXYVKCKXJSK42XE37F33ZW6DO3NXMVYX2TUA7I3XLLBL5YJ776VSKKA25TEN2QPGKEDH7MTOAYEBZRWFDQK5D7EOR7S75DGEEQ2N4CS5YAC3KHBGCE4JLAM6N42XNRMVIIEMPYWFM5YBPYJQBE3WYEGEEB5H5TLVRAE5R2WSDY6E2Z6ESHTHUYRIYM6HM4G2AJIZ2YP63L47MMBAWBTL7HGR6LSZAOJHBCLBUJRHDKE2WJVKU4UWNDKEUVDM556CWCG5CSKYUAHJAYGAE6LLNIJPWQ62BINWTTWUGUBX2TLH3DQCVC5C7QB4XY5PUDJT4Y3KE6TE7B43V2ES7AWYRPO72DMGDL6SCERRLMLAOYOFCN4JBO7Q";
    public static String DEFAULT_PRIVATE_KEY = "2DJ7FVDNFYWYEFT6YLHI5F2NMWTWUM5DCX572J7BHETJTXTWHX3B4LUYD6TGJKU47GT5EIPLKXVBUCI6OK5ZOKWH6K67BGF2XPZNCBIHTA6P2ZTRPE6N2WISQDTUPTOBS7JIQCRADQM4UMODILF6MBXURZQRABX6GYUU5AR5KTR2YG6J2PBCXRHMC333MFDZCJMP75XMOEHWU3WTGDA7ZRNJP2VSSQYFU6VPWPUTY3A7JC2EOB7MVMJZUSZRHF5BTQ44ZDVBYFTL5YRRJRAQJCCJLIKR3HE62NU6SJ7H6JP2F22XEYPRB6ITSLFQY6FEDGWKIWLENDOFABIJY6FEDXA7VAKGWCER4LGP3HKH3JNZ5XRJEPRF7UEJJ6RUHAO4NHVQBGK3FBPOTESSL2BAR6445UV6PBBVJOTZYXS65D2YWQU245RWSYXSUVJGZUPV4W675BFUGBFW4L4DG2FRV63H6E76DF3E3AEJNGYCQD6YVKCWYEVQAAM5PANGYHMY3V4VASRO36M5U23ZXD6NV2Z5QNU4TUTWSQULSWMBIGW7BWJMBZ4CSLDYIGNWAVH26USHP3RXRQOVBF23SG523NK72PEIWRPJQRNICWMAEAKFQ4W64J7KKW6I7V7GTHN7BLNYCGO7UZDI34Q32Y6VKPQFQFMSVBNVN2HV2YH7P7ZGHHMIPKWTOLANV4CK5ZCYIPOR2EWP2RTDA2MI3D6CQQKMYTT7DXJA2K7I7M45L3DYLIWOT2TGCDSRZR2RT7AFHYFM2O5YX2LR3XWMY7JB6X7LPAYX4NCQTHLN6TBWYQCROE2YWPCD4EIQA3KDNXCXEP5M7DONTCCDA3M5SH4VPE6U5FXNNARG3IDQ37TXPBOJQOCEDGTQSGRYVGSYLBEX2ZVXS57M7TQHM5ZPWT4EXYFB2AJQFX34PMO6XOGUYWMR7HCVQ2AMV5K5KQHBOATEMW4DXZBWOUDWGM4YK3WR5COFIPDIPHWUQ4WYI3U6RXTR33LAWODTALWVIZTSVZLWWFFFUQ2ZAVIVDDWLFJB6QY6FKQFXNS5SZUNAJAT3X6UQXDYOFUHY764725FBGIHU42AYMFXGJ64AKMEB3EW4GSW2GR3VUYS4G3PAZQSIXGT2JHYFA2MNLVETER44A2V4WM44UVPL4YH7NOVC2UONX7BQXHTCRSWN4CZSJCYO5HO6XTE45MISNOZSFK6S5P2OSNRLVMRF73AS2BHBORKXKQFOUNAHVVWXW6JJL2X5M2P7JQJJV4Z47LKUETXFV5WR4MBH4Z3RR2RB2UBFIQHEM3JD7BCXMKSOJIG2D6METMMQRCXDUUXTTIYLK2YN7KA3Y6O45OBJMFPUHMXCHXELDKEUN3J7EVTQ5KT4X7QSEA6APPPGMQZPJR4PHUKUF6H44KNQHWMX4FBWIBZFEYYSJAJHAIZKIE5JSY7JDWI3Z7GK2GZFPX55TNWCVNN25YZ6EA66TYMGEATRKLIONRTUNBGERC74DOMHL426X2CH2Q7LICYECR4QYZ7IDRO5DQ7MDBT4EWE4CHPJZQI2FWCLSTRK7JPXAAYIQ57725M3XBIWQGST5HUMSHSIRTRDYG4VKPNGRT4GZTH2QK2IBLTDY4DUUOKKHLUILYFKD42K7SQRY6YDIPUP4DAGOI4XNKABDUPTMHUUFDWUEFPLEEZWOBQXYT3OQMNRYIQORGJM667GSVMBPGTWDNAC4AAJ7B3S565YNG2PGQPZSHCPUZPADTJEGPKKVM6U3IBWL7O2JK2URTHM2QULERI6GJGGDX6JSZROUGH6HEMQIABGYMFOQ5LEWLWDOOUE4YBBUVESG3MIAPA35KJPO64JPYXNLDQPKXY4VZHRZAJ2Q265IUYU6NIKBY53CZSH3H5GXUUTXJ4QSINRU6TTV7CIK2E7HLQUSEFDNU6CDEOMDU74QI26JK5AEC7QNY2LEPYLNFUOSZVCUCK64VJO6ZOD5I5YCHPOQCAMTJYLAHKSANZTRKB4JKCRZMY3DMZQU7XY2IEITRQ77NV7WKVXASBWL7EM475MFAI4ZGNV4QV7KZSHHCIDNVE7TVMGKQBZTRQJFHD7SUX5ILJJKAP5OEFGWCYFTT465A6F5N4DPWDB72AE67TDSKNYQAPYPUIK25LAO3LDOVJEAMDMEH4KXMF5XIVCBMH7TAUNXXY363U4DZDAPVXV4ETUXVOKEYR7KJ3V7CJVASZDYRE2NGRBM5BQZVR722NZ672I63HLFB6AJUA3HMAU5B6HTGBKEFMIA75QTJXVYXS47XHJLMSFHMP3BP67SVNLWLKBRTHFT4LSJX53RAYLMAEQUCZBAY4KGBLFKAYYYKSNLGSCKNB77OXKHINBH7SMQDJCGMJLQNZ27KQZIQ3QEBTLG33MWM3UF7D5IZTWGL4X72XUILMRDCH7GMVPMRJGWQHBRNZPN47KZ3HAPWVO2CTKDL33YKDRRZFS3I65YSEHCPO47V5UL3E7BOV3BFI73ITP573FNQXUTRQWWQMBQIK5EIDLQNIVUAQTHQCULTYOXJV4U54BVPEAZUOUFQLSQJZAFIJK3UGKKBJSQRY4L7QMZ7IIOCGBB7GDOKCEWCSL5M7PC6PA4MEGP2XKMATHGCAHE3JP42O5VVHWNMGYUAKJBJ2TV3N63K4A3EZJ47BKQITFJFWSEMZGLZ2J2VRMXFWF7XFSHRMAA7NS7A4DOCKCXNVWFXTC54CN2YEBPJXT4CHYTGO2BQP25Z6QCW2UHTLH6D67POR5JWFOUYQ7CHFEWAGHFMMCVRQLGM5IYCQAOOO7FHF5IW53V344QDXCWKVIGXWB2VWDDNPTR2RQNNXNEGF6IBIPDRB55VO3ZTKLB7K4QPTPMHWCNHGKRYBUINDRYXX2ITIT3K3HG7MQ6NKF56JT7EXLJRNO4JJGUZYQMLCJLLKXOVIZ6EPFJ24FEZOF3GTFM5UCQ2TLC2GIUSSO42ENMILLYWDXRLHTERWYRDGO6ITVNW2PVG6F6MFVZE7765YWCMNJXQKV3Z25J7TZTXA3KKEZVSMX7QFY3VBS7USEZ5YARHONIAS37VJRKFVBAK2GERB6P4BC2ZOKNRL42O573PQD2SGS6SYZQ7DGNKUHP3NXISA6YVMKGXYPHV4OF3WEOPFJTTPEAFSDR2Z4Z7GLZICI4RF4AUKNJVTCYDU4VBVR6LRNEPT2CIE7WTJJG6FVSR4WPDGUUPDKUS2S5H46RENLTB4IRPPKYAYLX467V63AO2TWOUHBLR62NV5V3FPZRSGRTTN233NOOBKZPSFI44D5I5FGNPTCWV3PGWELGQTY6MLCSWZFAS44NEVJFW5GO5OEMLK4WVVP7UQQREQTBP4A4M2ATKRS36BULK4KIVR2YFPXVFJVU6YRAFE54KZ3SSCAVCSEJHTXPDD4JACXAK3JWNILCMIQE3LOM4ZJOIZFNWKAMKMPM6WK5VC6T4DVQF52HDOIXM3FWB72RYRK5NA7ANBDYTZIWWYOQ6QS7AOC5ZJUKR532JI6OWIFDRGFH6XXIJNQGD2KY4G3YT64LF56AXWWZNDRQ3MGC5ZJEWHFEJUBSGUUTA3WLLIVR3E5FBPDD3TAAYYEWSZ2AKDDLU6GKUFX2JMIDK5QKKPXU5DJUSWDHTW76TOKIMGYLQSPWAC2ZQIJV3FB6FV6NO2QS4FKDWRR3WCTF3IC6QFM6OJAFNKR7WE2U6MPS7W6FHFPEU65VCWY6MH436OOSVUC5SVJ7KB435PO7LNPC7P34LDEFBVQEB5PJQXFDHECAVTVVCMMYWT4IAEIG235W4Z3V5GZWEAYOD65I3MZ4ZLJM52IUAUT5VNAVJK3GPTHDOF7LRHVHDTSHO2URE4WGP5PL77Z3M3KRSE4UIX5BR7M45QULHIEDA7ONIT44OKLZ5OOAPURACNXLYS6FMQFVDJQBNNGNEBICAQAFA6ROW4MPBCGNRXBUD6J3YX7X2MKJGV6R4ZOIDNB2MSWSQDT3RJS45QNWTCJYQ2G3TBGQ3Z7T5N5SRQ4WZMKMQMBLJJRRMEG2ZTNB6XS5MHK255H24MMUYSNJ6CPXF6EMMHY43FMHXCDXA4DDBI6BQIJQUOGLNBCZNMMSLVJEV3ZDKONYBZLCO3UICKXJVYARPDJNP6DZIF4PMZSUJHFKGRHNWTUJZTVPFDLWUD2Y3RZ33TJGDMX3FPWNFJJHAEBPPDZXADNGLGS6NT6GBM64I6YDDOC3FGGE45WWMZGJIP4HN4HFQKXJS6RMIM32Z3OQVBWID36HAVAZK75T25JHI6JIZURO5NDM6AXANOT5SDNDDESEBUMFJHMYDM2QNPG4VXL6XGHEBVCZTDPKXV5N7GISOEFGEXADY33K5SVFQPKELFQ7Q3Z5BYFEAU6YZH3QGT54MPIMFOPKGJ34VS7DZ2FWUZRZYOSDCHVIRBMPFTW2WALPPBQXNVQENGA4E3EU7WOVTX6GO7GPQVZ3RAIZYPF3SSIX7AMWUIRUKDJIL56GQ5FVYVQBEHBGQPFH3STZRZJVTCBUH5N2BTH4DBNVTDLWY2TTT5GPJ7BEWTPAIQO4PPRPFBVXE3TTCWNED5Z4RM6W5QAZO4QR2CZ45IFXNE3HQV47YVZ3DQSEQVDUAXS3G6ZNLJ52PXU3QJVCL24HEYUNNC75CW3ZHKC332Y43DMEQUIED53TDCOXF7L4EBAOAA233MWYTGY4HPSYME4HHZOSBRYQHFBFEZLCPCK4Q5WZRK34B3XGQMILACP6QEIZDGDCJLIQB326DPXG67J3DJIQ635BLMWM5INMEN4NABRZHT53ZTEMZPI4OA3YNJ53K4LL7WU5IVCW564KJSU5HQNNEVF2PPS5XHEUCDEAZS2VHM6DVQSBR2VXU64GLA33EX4XEPRULWL2I4V6HRHKGJOEMKA4HGWFR5YXN4RYXS3TMH2LSV4NUTOKWPTHL3YP5N3UN6JWIYPXPOBLAYT4KQETRR7SX3FEGXG5K2ZPV4WN34CQR5BOUDBAB6WWURIUYFAUJVJDP2BVTPE3CLHBI2BNLVUCC5HR7OF4NORS6XMVIWRBBMGFQ57TFD3G2JNYWCH25QFQSTW3L6QRAJY";
    private String publicKey;
    private String privateKey;

    public KeyStringCrypt() {
        this(DEFAULT_PUBLIC_KEY, DEFAULT_PRIVATE_KEY);
    }

    public KeyStringCrypt(String publicKey, String privateKey) {
        this.publicKey = AesCipher.get().decrypt(cleanKeyString(publicKey));
        this.privateKey = AesCipher.get().decrypt(cleanKeyString(privateKey));
    }

    public void setPublicKey(String publicKey) {
        this.publicKey = AesCipher.get().decrypt(cleanKeyString(publicKey));
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = AesCipher.get().decrypt(cleanKeyString(privateKey));
    }

    public String encrypt(String text) {
        String data = Base62.encode(RsaCrypt.encryptByPrivateKey(text, privateKey));
        return "# rsa \r\n" + KeyStringUtils.wrapToLines(data, 64);
    }

    public String decrypt(String text) {
        String src = trimComment(text);
        String data = Base62.decode(cleanKeyString(src));
        return RsaCrypt.decryptByPublicKey(data, publicKey);
    }

    private String trimComment(String text) {
        try {
            BufferedReader reader = new BufferedReader(new StringReader(text));
            StringBuilder result = new StringBuilder();
            String line = reader.readLine();
            while (line != null) {
                if (!line.trim().startsWith("#")) {
                    result.append(line);
                }
                line = reader.readLine();
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private boolean isBlank(String s) {
        return s == null || s.trim().length() == 0;
    }

}
